package com.jichangxiu.common.entity.bo;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.jichangxiu.common.constant.Constant;
import com.jichangxiu.common.constant.ErrorCode;
import com.jichangxiu.common.exception.FrameworkException;
import com.jichangxiu.common.utils.StrUtils;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

import java.util.List;

/**
 * Result:
 *
 * @author Jcx
 * @create 2023-04-03 21:49
 */
@Data
@Schema(description = "响应对象")
public class Result<T> {

    @Schema(description = "请求是否成功")
    private Boolean status = true;

    @Schema(description = "编码 0 表示成功")
    private String code = "0";

    @Schema(description = "消息内容")
    private String msg = "成功";

    @Schema(description = "响应数据")
    private T data;

    public static <T> Result<T> ok(String msg, T data) {
        Result<T> result = new Result<>();
        result.setStatus(true);
        result.setCode(Constant.SUCCESS);
        result.setMsg(msg);
        result.setData(data);
        return result;
    }

    public static <T> Result<T> ok(T data) {
        return ok("操作成功", data);
    }

    public static <T> Result<T> ok() {
        return ok(null);
    }

    public static <T> Result<T> no(String code, String msg) {
        Result<T> result = new Result<>();
        result.setStatus(false);
        result.setCode(code);
        result.setMsg(msg);
        return result;
    }

    public static <T> Result<T> no(String msg) {
        return no(Constant.FAIL, msg);
    }

    public static <T> Result<T> no() {
        return no(Constant.FAIL, "操作失败");
    }

    public static <T> Result<T> no(ErrorCode errorCode) {
        return no(errorCode.getCode(), errorCode.getMsg());
    }

    public Result<T> MSG(String msg) {
        this.setMsg(msg);
        return this;
    }

    public Result<T> DATA(T data) {
        this.setData(data);
        return this;
    }

    public static Object toResult(Object body) {
        try {
            // 如果对象是空的，则返回成功提示
            if (ObjectUtil.isEmpty(body)) {
                return JSONUtil.parseObj(Result.ok());
            }

            // 如果对象是 String 则需要将返回内容放入 msg 中一份
            if (body instanceof String) {
                String str = String.valueOf(body);
                if (StrUtil.isNotEmpty(str)) {
                    // 去除字符串前后双引号
                    str = str.startsWith("\"") ? str.substring(1) : str;
                    str = str.endsWith("\"") ? str.substring(0, str.length() - 1) : str;
                }
                return JSONUtil.parseObj(Result.ok("操作成功", str));
            }

            // 如果是 List 对象
            if (body instanceof List<?>) {
                // 处理时间
                try {
                    List<Object> objectList = (List<Object>) body;
                    if (ObjectUtil.isEmpty(objectList)) {
                        return JSONUtil.parseObj(Result.ok(body));
                    }
                    if (objectList.get(0) instanceof String) {
                        return JSONUtil.parseObj(Result.ok(body));
                    } else {
                        List<Record> recordList = (List<Record>) body;
                        return JSONUtil.parseObj(Result.ok(StrUtils.handleTime(recordList)));
                    }
                } catch (Exception ex) {
                    List<Record> recordList = Record.getRecordByList((List<?>) body);
                    return JSONUtil.parseObj(Result.ok(StrUtils.handleTime(recordList)));
                }
            }

            // 如果是分页数据
            if (body instanceof PageData<?>) {
                PageData<?> pageData = (PageData<?>) body;
                List<?> rows = pageData.getRecords();
                try {
                    return JSONUtil.parseObj(Result.ok(PageData.build(pageData.getTotal(), StrUtils.handleTime((List<Record>) rows))));
                } catch (Exception ex) {
                    return JSONUtil.parseObj(Result.ok(PageData.build(pageData.getTotal(), StrUtils.handleTime(Record.getRecordByList(rows)))));
                }
            }

            // 如果就是 Result 对象直接返回
            if (body instanceof Result) {
                // 处理时间
                Record model = Record.getRecordByModel(body);
                Record data = model.getModel("data", Record.class);
                if (ObjectUtil.isNotEmpty(data)) {
                    model.set("data", StrUtils.handleTime(ListUtil.toList(data)).get(0));
                }
                return JSONUtil.parseObj(model);
            }

            // 防止 object instanceof Result 没有被识别
            Record record = Record.getRecordByModel(body);
            if (StrUtil.isNotEmpty(record.getStr("status"))
                    && StrUtil.isNotEmpty(record.getStr("code"))
                    && StrUtil.isNotEmpty(record.getStr("msg"))) {
                // 处理时间
                Record data = record.getModel("data", Record.class);
                if (ObjectUtil.isNotEmpty(data)) {
                    record.set("data", StrUtils.handleTime(ListUtil.toList(data)).get(0));
                }
                return JSONUtil.parseObj(record);
            }

            // 防止 Record.getRecordByModel(object) 没有被识别
            String json = JSONUtil.toJsonStr(body);
            if (JSONUtil.isTypeJSONObject(json)) {
                JSONObject jsonObject = JSONUtil.parseObj(json);
                // 如果本来就是 Result 对象，则不需要在进行包装，直接返回。
                if (StrUtil.isNotEmpty(jsonObject.getStr("status"))
                        && StrUtil.isNotEmpty(jsonObject.getStr("code"))
                        && StrUtil.isNotEmpty(jsonObject.getStr("msg"))) {
                    // 处理时间
                    Record data = Record.getRecordByModel(jsonObject.getJSONObject("data"));
                    if (ObjectUtil.isNotEmpty(data)) {
                        jsonObject.set("data", StrUtils.handleTime(ListUtil.toList(data)).get(0));
                    }
                    return jsonObject;
                }
            }

            // 处理时间
            // 其余返回
            return JSONUtil.parseObj(Result.ok(StrUtils.handleTime(ListUtil.toList(Record.getRecordByModel(body))).get(0)));
        } catch (Exception exception) {
            // JSON 转换失败
            throw FrameworkException.build("统一返回值封装失败", exception);
        }
    }

}
